package com.molichuxing.gateway.bff.orders.services.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.contants.RedisKeyConst;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.framework.utils.RedisLock;
import com.molichuxing.framework.utils.RedisUtil;
import com.molichuxing.gateway.bff.orders.convertor.Convert;
import com.molichuxing.gateway.bff.orders.entity.request.create.OrderCreateVo;
import com.molichuxing.gateway.bff.orders.entity.request.modify.TradeCancelModifyVo;
import com.molichuxing.gateway.bff.orders.entity.request.modify.TradeDeliveryModifyVo;
import com.molichuxing.gateway.bff.orders.entity.response.DeliveryResultVo;
import com.molichuxing.gateway.bff.orders.entity.response.OrderVo;
import com.molichuxing.gateway.bff.orders.services.OrderTradeBffService;
import com.molichuxing.gateway.contants.OrderConst;
import com.molichuxing.gateway.exception.DealerExceptionCodeEnum;
import com.molichuxing.gateway.exception.GoodsExceptionCodeEnum;
import com.molichuxing.gateway.exception.OrderBffExceptionCodeEnum;
import com.molichuxing.gateway.property.OrderCreateTypeEnum;
import com.molichuxing.gateway.utils.OrderUtil;
import com.molichuxing.services.business.dto.request.create.*;
import com.molichuxing.services.business.dto.request.modify.DeliveryModifyBizDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.*;
import com.molichuxing.services.infrastructure.dto.request.create.MessageCenterCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.MessageContentCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.NotifyPushCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.IovFenceBindingModifyDto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 订单交易bff
 *
 * @author zoumingyu
 * @date 2019年9月19日
 *
 */
@Service("orderDeliveryBffService")
public class OrderTradeBffServiceImpl implements OrderTradeBffService {
	private static final Logger logger = LoggerFactory.getLogger(OrderTradeBffServiceImpl.class);

	private final static List<String> VIRTUAL_PHONE = Arrays.asList("170", "171", "175", "165");

	@Resource
	private RedisUtil redisUtil;

	@Resource
	private OrderSubscribeService orderSubscribeService;

	@Resource
	private OrderMileageService orderMileageService;

	@Resource
	private OrderBizService orderBizService;

	@Resource
	private OrderExclusivelBizService orderExclusivelBizService;

	@Resource
	private OrderSubscribeBizService orderSubscribeBizService;

	@Resource
	private OrderPurchaseBizService orderPurchaseBizService;

	@Resource
	private OrderTradeBizService orderTradeBizService;

	@Resource
	private OrderRenewBizService orderRenewBizService;

	@Resource
	private OrderDelayBizService orderDelayBizService;

	@Resource
	private CarService carService;

	@Resource
	private CarBizService carBizService;

	@Resource
	private StoreBizService storeBizService;

	@Resource
	private DealerService dealerService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private GoodsBizService goodsBizService;

	@Resource
	private IovFenceService iovFenceService;

	@Resource
	private StockCarService stockCarService;

	@Resource
	private DrivingLicenseService drivingLicenseService;

	@Resource
	private SmsBizService smsBizService;

	@Resource
	private MessageCenterBizService messageCenterBizService;

	@Resource
	private UserService userService;

	@Resource
	private NotifyPushService notifyPushService;

	@Resource
	private MessageTemplateService messageTemplateService;
	
	@Resource
	private VehicleBizService vehicleBizService;

	/**
	 * 订单新增
	 * 
	 * @param createVo
	 * @return orderCode：订单号
	 * @throws Exception
	 */
	@Override
	public OrderVo createOrder(OrderCreateVo createVo) throws BizException, Exception {
		OrderVo result = null;
		RedisLock lock = new RedisLock(redisUtil,
				RedisKeyConst.LOCK_TOKEN_KEY + "order_" + createVo.getOperateId(), 10000);

		if (lock.tryLock()) {
			try {
				// 判断生成订单类型
				if (OrderCreateTypeEnum.EXCLUSIVEL.equals(createVo.getCreateType())) {
					// 生成专属订单
					result = createExclusivel(createVo);
					//发送防诈骗短信
					sendSmsPreventFraud(createVo.getPhone());
				} else if (OrderCreateTypeEnum.SUBSCRIBE.equals(createVo.getCreateType())) {
					// 生成订阅订单
					result = createSubscribe(createVo);
					//发送防诈骗短信
					sendSmsPreventFraud(createVo.getPhone());
				} else if (OrderCreateTypeEnum.PURCHASED.equals(createVo.getCreateType())) {
					// 生成订阅加购订单
					result = createPurchased(createVo);
				} else if (OrderCreateTypeEnum.RENEW.equals(createVo.getCreateType())) {
					// 生成订阅续租订单
					result = createRenew(createVo);
				}
			} finally {
				lock.unlock();
			}
		} else {
			Thread.sleep(3000);
			throw new BizException("请勿重复提交");
		}
		return result;
	}

	/**
	 * 验证门店信息
	 * 
	 * @param createVo
	 * @return
	 * @throws Exception
	 */
	private StoreBaseBizDto checkStore(OrderCreateVo createVo) throws Exception {
		StoreBaseBizDto store = null;
		if (OrderSourceEnum.AIO.equals(createVo.getSource())) {
			// 智能终端下单
			store = checkStore(createVo.getDeviceNum(), createVo.getSource());
			createVo.setStoreId(store.getStoreId());
		} else {
			// 其他来源
			store = checkStore(createVo.getStoreId(), createVo.getSource());
		}

		return store;
	}

	/**
	 * 验证商品信息
	 * 
	 * @param createVo
	 * @param dealerId
	 * @return
	 * @throws Exception
	 */
	private GoodsOrderBizDto checkGoods(OrderCreateVo createVo, Integer dealerId) throws Exception {
		// 验证商品信息
		if (goodsBizService.isProhibited(createVo.getGoodsId(), dealerId)) {
			logger.error("[checkGoods]商品(" + createVo.getGoodsId() + ")未绑定或下架");
			throw new BizException(GoodsExceptionCodeEnum.PROHIBITION.getCode(),
					GoodsExceptionCodeEnum.PROHIBITION.getMessage());
		}
		// 查询商品信息
		GoodsOrderBizDto goods = goodsBizService.getGoodsForOrder(createVo.getGoodsId(), createVo.getPackageId());
		if (goods == null) {
			logger.error("[checkGoods]商品(" + createVo.getGoodsId() + ")不存在");
			throw new BizException(GoodsExceptionCodeEnum.NONENTITY.getCode(),
					GoodsExceptionCodeEnum.NONENTITY.getMessage());
		}

		return goods;
	}

	/**
	 * 生成订阅续租订单
	 * 
	 * @param createVo
	 * @return
	 */
	private OrderVo createRenew(OrderCreateVo createVo) throws BizException, Exception {
		OrderVo result = null;
		// 根据订单号查询主订单信息
		OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(createVo.getOrderCode());
		if (orderSubscribeDto == null) {
			logger.error("[createRenew]订单({})不存在", createVo.getOrderCode());
			throw new BizException("订单不存在");
		}

		// 验证门店信息
		createVo.setStoreId(orderSubscribeDto.getPlaceStoreId());
		StoreBaseBizDto store = checkStore(createVo);
		// 验证商品
		GoodsOrderBizDto goods = checkGoods(createVo, store.getDealerId());
		// 验证是否存在续订订单
		if (orderSubscribeDto.getIsHaveSuborder()) {
			logger.error("[createRenew]订单({})已存在续订订单", createVo.getOrderCode());
			throw new BizException(OrderBffExceptionCodeEnum.CANNOT_RELET.getCode(), "该订单已续订,请勿重复续订");
		}
		// 验证是否存在未支付加购订单
		OrderSubscribeDto renew = orderSubscribeService.getOrderSubscribeByParent(createVo.getOrderCode(),
				OrderSubscribeStatusEnum.TRADE_UNPAID);
		if (renew != null) {
			logger.error("[createRenew]订单({})已存在待付款续订订单", createVo.getOrderCode());
			throw new BizException(OrderBffExceptionCodeEnum.CANNOT_RELET.getCode(), "您有一条待付款的续订订单");
		}
		// 验证时间
		OrderUtil.verifyDate(orderSubscribeDto.getLeaseExpire(), createVo.getOrderCode(), OrderCreateTypeEnum.RENEW,
				logger);
		// 验证里程并返回超里程数
		Integer beyondMileage = getBeyondMileage(orderSubscribeDto);
		if (beyondMileage >= 0) {
			logger.error("[createRenew]订单({})已超里程(超里程数：{})", createVo.getOrderCode(), beyondMileage);
			throw new BizException(OrderBffExceptionCodeEnum.CANNOT_RELET.getCode(),
					"因您操作超时，当前订单车辆已超程，不能办理续订，请办理加购里程，并结算当前超程的费用。");
		}
		// 新增续订订单
		result = new OrderVo();
		OrderRenewCreateBizDto createBizDto = Convert.toOrderRenewCreateBizDto(createVo, goods);
		createBizDto.setCarId(orderSubscribeDto.getCarId());
		// 起租日
		createBizDto.setLeaseInception(orderSubscribeDto.getLeaseExpire().plusDays(1L));
		// 截止日（起租日加租期）
		createBizDto.setLeaseExpire(createBizDto.getLeaseInception().plusMonths(goods.getUseVehicleTime().longValue()));
		Long orderCode = orderRenewBizService.ceateRenew(createBizDto);
		result.setOrderCode(orderCode);

		// 添加延时任务
		try {
			OrderDelayCreateBizDto delayCreateBizDto = new OrderDelayCreateBizDto();
			BeanUtils.copyProperties(createBizDto, delayCreateBizDto);
			delayCreateBizDto.setOrderCode(orderCode);
			delayCreateBizDto.setUserId(createBizDto.getUserId());
			delayCreateBizDto.setExpireDate(
					DateUtil.plus(createBizDto.getOrderTime(), OrderConst.ORDER_VALID_TIME, ChronoUnit.MINUTES));
			orderDelayBizService.create(delayCreateBizDto);
		} catch (Exception e) {
			logger.error("[createRenew]订阅续订订单添加延时任务异常：", e);
		}

		return result;
	}

	/**
	 * 生成订阅加购订单
	 * 
	 * @param createVo
	 * @return
	 * @throws BizException
	 */
	private OrderVo createPurchased(OrderCreateVo createVo) throws BizException, Exception {
		OrderVo result = null;
		// 根据订单号查询主订单信息
		OrderSubscribeDto orderSubscribeDto = orderSubscribeService.getOrderSubscribe(createVo.getOrderCode());
		if (orderSubscribeDto == null) {
			logger.error("[createPurchased]订单({})不存在", createVo.getOrderCode());
			throw new BizException("订单不存在");
		}

		// 验证门店信息
		createVo.setStoreId(orderSubscribeDto.getPlaceStoreId());
		StoreBaseBizDto store = checkStore(createVo);
		// 验证商品
		GoodsOrderBizDto goods = checkGoods(createVo, store.getDealerId());
		// 验证是否同一种商品
		if (!orderSubscribeDto.getGoodsId().equals(createVo.getGoodsId())) {
			logger.error("[createPurchased]订单商品({})和加购商品({})不一致", orderSubscribeDto.getGoodsId(),
					createVo.getGoodsId());
			throw new BizException("商品信息异常");
		}
		// 验证是否存在未支付加购订单
		List<OrderMileageDto> orderPurchases = orderMileageService.getOrderMileageList(createVo.getOrderCode(),
				OrderMileagePayStatusEnum.WAIT);
		if (orderPurchases != null && !orderPurchases.isEmpty()) {
			logger.error("[createPurchased]订单({})存在未支付加购订单", createVo.getOrderCode());
			throw new BizException(OrderBffExceptionCodeEnum.PURCHASED_EXIST.getCode(),
					OrderBffExceptionCodeEnum.PURCHASED_EXIST.getMessage());
		}

		// 验证时间
		OrderUtil.verifyDate(orderSubscribeDto.getLeaseExpire(), createVo.getOrderCode(), OrderCreateTypeEnum.PURCHASED,
				logger);
		// 验证里程并返回超里程数
		Integer beyondMileage = getBeyondMileage(orderSubscribeDto);
		beyondMileage = beyondMileage < 0 ? 0 : beyondMileage;
		// 新增加购订单
		result = new OrderVo();
		OrderPurchaseCreateBizDto createBizDto = Convert.toOrderPurchaseCreateBizDto(createVo, goods, beyondMileage);
		Long orderCode = orderPurchaseBizService.createOrderPurchase(createBizDto);
		result.setOrderCode(orderCode);

		// 添加延时任务
		try {
			OrderDelayCreateBizDto delayCreateBizDto = new OrderDelayCreateBizDto();
			BeanUtils.copyProperties(createBizDto, delayCreateBizDto);
			delayCreateBizDto.setOrderCode(orderCode);
			delayCreateBizDto.setUserId(createBizDto.getUserId());
			delayCreateBizDto.setExpireDate(
					DateUtil.plus(createBizDto.getPurchaseTime(), OrderConst.PURCHASE_VALID_TIME, ChronoUnit.MINUTES));
			orderDelayBizService.create(delayCreateBizDto);
		} catch (Exception e) {
			logger.error("[createPurchased]订阅订单添加延时任务异常：", e);
		}

		return result;
	}

	/**
	 * 获取超里程数
	 * 
	 * @param orderSubscribeDto
	 * @return
	 */
	private Integer getBeyondMileage(OrderSubscribeDto orderSubscribeDto) {
		Integer result = 0;
		// 查询车辆信息
		CarDto carDto = carService.getCarById(orderSubscribeDto.getCarId());
		// 车辆当前行驶里程数
		Integer currentMileage = iovCarService.getCurrentMileage(carDto.getVin());
		// 车辆购买里程数
		// Integer orderMileage = orderSubscribeDto.getBaseMileage() +
		// orderSubscribeDto.getPackageMileage()
		// + orderSubscribeDto.getGiftMileage();
		// // 查询加购里程信息
		// OrderPurchaseBizDto orderPurchaseBizDto = orderPurchaseBizService
		// .getOrderPurchase(orderSubscribeDto.getOrderCode());
		// if (orderPurchaseBizDto != null) {
		// orderMileage = orderMileage +
		// orderPurchaseBizDto.getTotalPurchaseMileage()
		// + orderPurchaseBizDto.getTotalBeyondMileage();
		// }
		// 计算超里程（当前行驶里程数-预警里程）
		result = currentMileage - orderSubscribeDto.getWarningMileage();

		return result;
	}

	/**
	 * 生成订阅订单
	 * 
	 * @param createVo
	 * @return
	 * @throws BizException
	 * @throws Exception
	 */
	private OrderVo createSubscribe(OrderCreateVo createVo) throws BizException, Exception {
		OrderVo result = null;
		// 验证门店信息
		StoreBaseBizDto store = checkStore(createVo);
		// 验证商品
		GoodsOrderBizDto goods = checkGoods(createVo, store.getDealerId());
		// TODO 验证风控

		// 验证手机号虚拟号段
		String roughly_phone = createVo.getPhone().substring(0, 3);
		if (VIRTUAL_PHONE.contains(roughly_phone)) {
			throw new BizException("该号段暂不支持下单");
		}

		// 验证用户是否存在订单
		OrderVerifyBizDto orderVerifyBizDto = orderBizService.orderVerify(createVo.getOperateId(), null);
		if (orderVerifyBizDto == null) {
			throw new BizException(1, "抱歉，您未通过征信验证");
		} else if (orderVerifyBizDto.getIsOrder()) {
			logger.error("[createOrderExclusivel]用户(" + createVo.getOperateId() + ")存在尚未完成订单");
			throw new BizException(OrderBffExceptionCodeEnum.HAVE_ORDER.getCode(), "抱歉，您名下已有订单尚未完成，暂时无法下单");
		}
		result = new OrderVo();
		OrderSubscribeCreateBizDto createBizDto = Convert.toOrderSubscribeCreateBizDto(createVo, goods);
		Long orderCode = orderSubscribeBizService.createOrderSubscribe(createBizDto);
		result.setOrderCode(orderCode);

		// 添加延时任务
		try {
			OrderDelayCreateBizDto delayCreateBizDto = new OrderDelayCreateBizDto();
			BeanUtils.copyProperties(createBizDto, delayCreateBizDto);
			delayCreateBizDto.setOrderCode(orderCode);
			delayCreateBizDto.setUserId(createBizDto.getUserId());
			delayCreateBizDto.setExpireDate(
					DateUtil.plus(createBizDto.getOrderTime(), OrderConst.ORDER_VALID_TIME, ChronoUnit.MINUTES));
			orderDelayBizService.create(delayCreateBizDto);
		} catch (Exception e) {
			logger.error("[createSubscribe]订阅订单添加延时任务异常：", e);
		}

		return result;
	}

	/**
	 * 生成专属订单
	 * 
	 * @param createVo
	 * @return
	 */
	private OrderVo createExclusivel(OrderCreateVo createVo) throws BizException, Exception {
		OrderVo result = null;
		// 验证门店信息
		StoreBaseBizDto store = checkStore(createVo);
		// 验证商品
		GoodsOrderBizDto goods = checkGoods(createVo, store.getDealerId());
		// TODO 验证风控

		// 验证手机号虚拟号段
		String roughly_phone = createVo.getPhone().substring(0, 3);
		if (VIRTUAL_PHONE.contains(roughly_phone)) {
			throw new BizException("该号段暂不支持下单");
		}

		// 验证用户是否存在订单
		OrderVerifyBizDto orderVerifyBizDto = orderBizService.orderVerify(createVo.getOperateId(), null);
		if (orderVerifyBizDto == null) {
			throw new BizException(1, "抱歉，您未通过征信验证");
		} else if (orderVerifyBizDto.getIsOrder()) {
			logger.error("[createOrderExclusivel]用户(" + createVo.getOperateId() + ")存在尚未完成订单");
			throw new BizException(OrderBffExceptionCodeEnum.HAVE_ORDER.getCode(), "抱歉，您名下已有订单尚未完成，暂时无法下单");
		}
		result = new OrderVo();
		OrderExclusivelCreateBizDto createBizDto = Convert.toOrderExclusivelCreateBizDto(createVo, goods);
		Long orderCode = orderExclusivelBizService.createOrderExclusivel(createBizDto);
		result.setOrderCode(orderCode);
		if (OrderExclusivelTypeEnum.TYPE_TWO.equals(createBizDto.getType())) {
			// 订悦里程不需要支付、倒计时
			result.setIsNeedPay(false);
			return result;
		}
		// 添加延时任务
		try {
			OrderDelayCreateBizDto delayCreateBizDto = new OrderDelayCreateBizDto();
			BeanUtils.copyProperties(createBizDto, delayCreateBizDto);
			delayCreateBizDto.setOrderCode(orderCode);
			delayCreateBizDto.setUserId(createBizDto.getUserId());
			delayCreateBizDto.setExpireDate(
					DateUtil.plus(createBizDto.getOrderTime(), OrderConst.ORDER_VALID_TIME, ChronoUnit.MINUTES));
			orderDelayBizService.create(delayCreateBizDto);
		} catch (Exception e) {
			logger.error("[createExclusivel]专属订单添加延时任务异常：", e);
		}

		return result;
	}

	/**
	 * 根据设备号（cpu）验证门店
	 * 
	 * @param deviceNum
	 *            设备号（cpu）
	 * @param orderSourceEnum
	 *            订单来源
	 * @throws Exception
	 */
	private StoreBaseBizDto checkStore(String deviceNum, OrderSourceEnum orderSourceEnum) throws Exception {
		return checkStore(storeBizService.getStoreBaseByCpu(deviceNum), deviceNum, null, orderSourceEnum);
	}

	/**
	 * 根据门店id验证门店
	 * 
	 * @param storeId
	 *            门店id
	 * @param orderSourceEnum
	 *            订单来源
	 * @throws Exception
	 */
	private StoreBaseBizDto checkStore(Integer storeId, OrderSourceEnum orderSourceEnum) throws Exception {
		return checkStore(storeBizService.getStoreBaseById(storeId), null, storeId, orderSourceEnum);
	}

	/**
	 * 验证门店
	 * 
	 * @param store
	 * @param deviceNum
	 * @param storeId
	 * @throws Exception
	 */
	private StoreBaseBizDto checkStore(StoreBaseBizDto store, String deviceNum, Integer storeId,
			OrderSourceEnum orderSource) throws Exception {
		if (store == null) {
			// 门店不存在
			logger.error("[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应门店不存在");
			throw new BizException(DealerExceptionCodeEnum.STORE_SUSPENSION.getCode(),
					OrderSourceEnum.AIO.equals(orderSource) ? DealerExceptionCodeEnum.STORE_SUSPENSION.getMessage()
							: "抱歉，本门店已暂停营业，无法继续办理业务");
		} else if (StoreStatusEnum.SUSPENSION.equals(store.getStatus())) {
			// 门店暂停营业
			logger.error("[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应门店暂停营业");
			throw new BizException(DealerExceptionCodeEnum.STORE_SUSPENSION.getCode(),
					OrderSourceEnum.AIO.equals(orderSource) ? DealerExceptionCodeEnum.STORE_SUSPENSION.getMessage()
							: "抱歉，本门店已暂停营业，无法继续办理业务");
		} else if (StoreStatusEnum.CLOSE.equals(store.getStatus())) {
			// 门店强制关店
			logger.error("[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应门店强制关店");
			throw new BizException(DealerExceptionCodeEnum.STORE_CLOSE.getCode(),
					OrderSourceEnum.AIO.equals(orderSource) ? DealerExceptionCodeEnum.STORE_CLOSE.getMessage()
							: "抱歉，本门店强制关店，无法继续办理业务");
		} else if (!store.getIsShow()) {
			// 门店不可显示
			logger.error("[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应门店不可显示");
			throw new BizException(DealerExceptionCodeEnum.STORE_SUSPENSION.getCode(),
					OrderSourceEnum.AIO.equals(orderSource) ? DealerExceptionCodeEnum.STORE_SUSPENSION.getMessage()
							: "抱歉，本门店已暂停营业，无法继续办理业务");
		} else if (!store.getIsSale()) {
			// 门店不可交易
			logger.error("[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应门店不可交易");
			throw new BizException(DealerExceptionCodeEnum.STORE_SUSPENSION.getCode(),
					OrderSourceEnum.AIO.equals(orderSource) ? DealerExceptionCodeEnum.STORE_SUSPENSION.getMessage()
							: "抱歉，本门店已暂停营业，无法继续办理业务");
		}
		// 验证经销商信息
		DealerDto dealer = dealerService.getDealerById(store.getDealerId());
		if (dealer == null) {
			// 经销商不存在
			logger.error(
					"[checkStore]设备(" + deviceNum + ")获取门店id(" + storeId + ")对应经销商(" + store.getDealerId() + ")不存在");
			throw new BizException(DealerExceptionCodeEnum.DEALER_SUSPENSION.getCode(), "抱歉，本门店暂时不能办理业务");
		} else if (DealerStatusEnum.SUSPENSION.getValue() == dealer.getStatus()) {
			logger.error("[checkStore]经销商(" + store.getDealerId() + ")暂停营业");
			throw new BizException(DealerExceptionCodeEnum.DEALER_SUSPENSION.getCode(), "抱歉，本门店暂时不能办理业务");
		} else if (DealerStatusEnum.CLOSE.getValue() == dealer.getStatus()) {
			logger.error("[checkStore]经销商(" + store.getDealerId() + ")终止合作");
			throw new BizException(DealerExceptionCodeEnum.DEALER_CLOSE.getCode(), "抱歉，本门店暂时不能办理业务");
		}

		return store;
	}

	/**
	 * 订单取消
	 * 
	 * @param modifyVo
	 * @return
	 */
	@Override
	public Boolean modifyCancel(TradeCancelModifyVo modifyVo) throws BizException, Exception {
		if (!orderTradeBizService.modifyCancel(Convert.toOrderCancelModifyBizDto(modifyVo))) {
			logger.error("[cancel]订单({})取消失败", modifyVo.getOrderCode());
			throw new BizException("订单取消失败");
		}
		// 删除延时任务
		try {
			orderDelayBizService.delete(modifyVo.getOrderCode());
		} catch (Exception e) {
			logger.error("[cancel]订单取消，删除延时任务异常：", e);
		}

		return true;
	}

	/**
	 * 订单提车
	 * 
	 * @param modifyVo
	 * @return
	 * @throws Exception
	 */
	@Override
	public DeliveryResultVo modifyDelivery(TradeDeliveryModifyVo modifyVo) throws BizException, Exception {
		DeliveryResultVo result = new DeliveryResultVo();
		// 验证订单信息
		OrderBizDto order = orderBizService.getOrder(modifyVo.getOrderCode());
		if (!checkOrder(order, result)) {
			return result;
		}
		OrderMemberBizDto orderMember = (OrderMemberBizDto) order;
		// 查询门店信息
		StoreBizDto store = storeBizService.getStoreDetailsByCpu(modifyVo.getDeviceNum());
		// 验证门店信息
		if (!checkStore(store, modifyVo.getDeviceNum(), orderMember.getPlaceStoreId(), result)) {
			return result;
		}
		// 查询车辆信息
		CarDto carDto = carService.getCarById(modifyVo.getCarId());
		// 判断车辆是否存在未处理异变里程，验证并修改车辆信息、保存车辆交接单信息
		if (!checkModifyCar(modifyVo, carDto, store, result)) {
			return result;
		}
		// 查询车辆当前里程
		Integer currentMileage = iovCarService.getCurrentMileage(carDto.getVin());
		// 计算订单预警里程(提车时车辆里程+基础里程+里程包里程+赠送里程)
		Integer warningMileage = 0;
		if (OrderTypeEnum.EXCLUSIVEL.equals(orderMember.getType())) {
			// 专属订单
			OrderExclusivelBizDto orderExclusivel = (OrderExclusivelBizDto) order;
			warningMileage = currentMileage + orderExclusivel.getLimitMileage();

		} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMember.getType())) {
			// 订阅订单
			OrderSubscribeBizDto orderSubscribe = (OrderSubscribeBizDto) order;
			warningMileage = currentMileage + orderSubscribe.getBaseMileage() + orderSubscribe.getPackageMileage()
					+ orderSubscribe.getGiftMileage();
		}
		// 保存交车信息并修改订单信息
		if (!orderTradeBizService
				.modifyDelivery(Convert.toOrderDeliveryModifyBizDto(modifyVo, warningMileage, store.getStoreId()))) {
			result.setResult(false);
			result.setExplain("订单异常");
			return result;
		}
		result.setResult(true);
		// 发送消息
		pushMsg(orderMember, carDto, store);

		return result;
	}

	private void pushMsg(OrderMemberBizDto orderMember, CarDto carDto, StoreBizDto store) {
		try {
			// 查询用户信息
			UserDto userDto = userService.getUser(orderMember.getUserId());
			JSONObject json = new JSONObject();
			// 门店
			json.put("store", store.getFullName());
			// 车牌
			json.put("plate", carDto.getLicencePlate());
			// 发送短信
			try {
				smsBizService.sendMessage(userDto.getPhone(), SmsTemplateEnum.ORDER_DELIVERY_SMS.getValue(),
						json.toJSONString(), null);
			} catch (Exception e) {
				logger.error("提车(" + orderMember.getOrderCode() + ")完成发送短信异常", e);
			}
			// 发送推送
			MessageTemplateDto messageTemplateDto = null;
			String body = null;
			String goodsName = null;
			try {
				// 查询车型信息
				VehicleNameBizDto vehicleName = vehicleBizService.getCarByModel(orderMember.getVehicleId());
				if (OrderTypeEnum.EXCLUSIVEL.equals(orderMember.getType())) {
					// 专属订单
					OrderExclusivelBizDto orderExclusivel = (OrderExclusivelBizDto) orderMember;
					String paymentMethodStr = OrderPaymentMethodEnum.INSTALLMENT.equals(
							orderExclusivel.getPaymentMethod()) ? "月付" : orderExclusivel.getPaymentMethod().getName();
					goodsName = vehicleName.getModelName() + " " + orderExclusivel.getTransportTime() + "期/"
							+ (orderExclusivel.getIsBuyback() ? "回购/" : "不回购/") + paymentMethodStr;
					messageTemplateDto = messageTemplateService
							.getByKey("push_delivery_vehicle_success");
					body = messageTemplateDto.getBody().replace("${goodsName}", goodsName);

				} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMember.getType())) {
					// 订阅订单
					OrderSubscribeBizDto orderSubscribe = (OrderSubscribeBizDto) orderMember;
					goodsName = vehicleName.getModelName() + " " + orderSubscribe.getTransportTime() + "个月/"
							+ orderSubscribe.getBaseMileage() + "公里, " + orderSubscribe.getPackageMileage() + "公里";
					messageTemplateDto = messageTemplateService
							.getByKey("push_delivery_vehicle_success_two");
					body = messageTemplateDto.getBody().replace("${buyStore}", store.getFullName())
							.replace("${goodsName}", goodsName)
							.replace("${licencePlate}", carDto.getLicencePlate())
							.replace("${date}", DateUtil.formatDate(orderSubscribe.getLeaseExpire(), "yyyy年MM月dd日"))
							.replace("${store}", store.getFullName());
				}
				// 推送
				NotifyPushCreateDto notifyPush = new NotifyPushCreateDto(Arrays.asList(userDto.getPhone()),
						messageTemplateDto.getSubject(),
						messageTemplateDto.getSubject(), body, body, null, "");
				notifyPushService.notifyPushByAlias(notifyPush);
			} catch (Exception e) {
				logger.error("提车(" + orderMember.getOrderCode() + ")完成发送短信异常", e);
			}

			// 保存消息
			MessageCenterCreateBizDto messageCenterCreateBizDto = new MessageCenterCreateBizDto();
			MessageCenterCreateDto messageCenterCreateDto = new MessageCenterCreateDto();
			messageCenterCreateDto.setUserId(userDto.getId());
			messageCenterCreateDto.setTitle("提车成功通知");
			messageCenterCreateDto.setMessage("您的订单已提取车辆，祝您用车愉快！");
			messageCenterCreateDto.setType(MessageCenterTypeEnum.CARRIAGE_SUCCESS_NOTICE.getValue());
			messageCenterCreateDto.setStatus(MessageCenterStatusEnum.UNREAD.getValue());
			List<MessageContentCreateDto> messageContentCreateDtos = new ArrayList<>();
			messageContentCreateDtos.add(new MessageContentCreateDto("订单号", orderMember.getOrderCode() + "", 1));
			messageContentCreateDtos.add(new MessageContentCreateDto("车辆名称", goodsName, 2));
			messageContentCreateDtos.add(new MessageContentCreateDto("车牌号", carDto.getLicencePlate(), 3));
			messageContentCreateDtos.add(new MessageContentCreateDto("提车时间",
					DateUtil.formatDate(LocalDateTime.now(), "yyyy年MM月dd日  HH:mm:ss"), 4));

			messageCenterCreateBizDto.setMessageCenterCreateDto(messageCenterCreateDto);
			messageCenterCreateBizDto.setMessageContentCreateDtoList(messageContentCreateDtos);
			messageCenterBizService.careteMessageCenterBiz(messageCenterCreateBizDto);
		} catch (Exception e) {
			String msg = "提车(" + orderMember.getOrderCode() + ")完成发送消息异常：";
			logger.error(msg, e);
		}

	}

	/**
	 * 验证并修改车辆信息、保存车辆交接单信息
	 * 
	 * @param modifyVo
	 * @param carDto
	 * @param store
	 * @param resultVo
	 * @return
	 */
	private boolean checkModifyCar(TradeDeliveryModifyVo modifyVo, CarDto carDto, StoreBizDto store,
			DeliveryResultVo resultVo) {
		boolean result = false;
		try {
			if (carDto == null) {
				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")不存在");
				OrderUtil.carFailed(resultVo);
				return result;
			} else if (CarsOperateStatusEnum.RENTED.getValue() == carDto.getStatus()) {
				// 车辆租赁中
				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")租赁中");
				OrderUtil.carFailed(resultVo);
				return result;
			} else if (CarsOperateStatusEnum.NOT_RENT.getValue() == carDto.getStatus()) {
				// 车辆不可租
				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")不可租");
				OrderUtil.carFailed(resultVo);
				return result;
			}
			// 验证里程?
			// if (!currentMileage.equals(modifyVo.getMileage())) {
			// // 检验单里程和车辆当前里程不一致
			// logger.error("[checkModifyCar]检验单里程(" + modifyVo.getMileage() +
			// ")和车辆当前里程(" + currentMileage + ")不一致");
			// OrderUtil.carFailed(resultVo);
			// return result;
			// }
			// 检验车辆是否在门店围栏中
//			if (!iovFenceService.getInfence(store.getFenceId(), carDto.getVin())) {
//				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")不在门店(" + store.getStoreId() + ")围栏("
//						+ store.getFenceId() + ")中");
//				OrderUtil.carFailed(resultVo);
//				return result;
//			}
			// 判断是否存在未处理异变里程
			if (iovCarService.getIsMileageExAlarms(carDto.getVin())) {
				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ":" + carDto.getVin() + ")存在未处理里程异变信息");
				OrderUtil.carFailed(resultVo);
				return result;
			}

			// 解绑围栏
			try {
				if (!deleteAllFence(carDto.getVin())) {
					logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")解绑围栏(" + store.getFenceId() + ")失败");
				}
			} catch (Exception e) {
				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")解绑围栏(" + store.getFenceId() + ")失败",e);
			}
//			if (!modifyBindingFence(store.getFenceId(), carDto.getVin())) {
//				logger.error("[checkModifyCar]车辆(" + modifyVo.getCarId() + ")解绑围栏(" + store.getFenceId() + ")失败");
//				OrderUtil.carFailed(resultVo);
//				return result;
//			}

			// 提车修改车辆信息、保存验车单信息
			DeliveryModifyBizDto modifyDto = Convert.toDeliveryModifyBizDto(modifyVo, store);
			if (carBizService.modifyDeliveryCar(modifyDto)) {
				// 库存状态改为已出租
				stockCarService.modifyCarStatus(modifyVo.getCarId(), StockCarCarStatusEnum.RENTED.getValue());
				// 车辆修改成功
				resultVo.setResult(true);
				result = true;
			} else {
				OrderUtil.carFailed(resultVo);
			}
		} catch (Exception e) {
			logger.error("[checkModifyCar]车辆异常(" + modifyVo + "):", e);
			OrderUtil.carFailed(resultVo);
		}
		return result;
	}

	/**
	 * 解绑围栏
	 * 
	 * @param fenceId
	 * @param vin
	 * @return
	 */
	private Boolean modifyBindingFence(Integer fenceId, String vin) {
		try {
			IovFenceBindingModifyDto dto = new IovFenceBindingModifyDto();
			if (null == fenceId || StringUtils.isBlank(vin)) {
				return false;
			}
			dto.setFenceId(Long.valueOf(fenceId));
			List<String> list = new ArrayList<>(1);
			list.add(vin);
			dto.setListVin(list);

			return iovFenceService.modifyBindingFence(dto);
		} catch (Exception e) {
			logger.error("解绑围栏异常：", e);
			return false;
		}
	}
	
	/**
	 * 解除该车辆绑定的所有围栏
	 * @param vin
	 * @return
	 */
	private Boolean deleteAllFence(String vin) {
		try {
			if (StringUtils.isBlank(vin)) {
				return false;
			}
			return iovFenceService.deleteAllFence(vin);
		} catch (Exception e) {
			logger.error("解绑围栏异常：", e);
			return false;
		}
	}

	/**
	 * 验证门店状态
	 * 
	 * @param cpu
	 *            大屏cpu
	 * @param placeStoreId
	 *            下单门店id
	 * @return
	 */
	private boolean checkStore(StoreBizDto store, String cpu, Integer placeStoreId, DeliveryResultVo resultVo) {
		boolean result = false;
		try {
			if (store == null) {
				// 门店不存在
				logger.error("[checkStore]大屏cpu(" + cpu + ")关联门店未查到");
				OrderUtil.storeClose(resultVo);
			} else if (!store.getStoreId().equals(placeStoreId)) {
				// 提车门店不是下单门店
				logger.error("[checkStore]提车门店(" + store.getStoreId() + ")不是下单门店(" + placeStoreId + ")");
				resultVo.setResult(false);
				resultVo.setExplain("请到下单门店提车！");
				result = false;
			} else if (StoreStatusEnum.SUSPENSION.equals(store.getStatus())) {
				// 门店暂停营业
				logger.error("[checkStore]门店(" + store.getStoreId() + ")已暂停营业");
				OrderUtil.storeSuspension(resultVo);
			} else if (StoreStatusEnum.CLOSE.equals(store.getStatus())) {
				// 门店强制关店
				logger.error("[checkStore]门店(" + store.getStoreId() + ")已强制关店");
				OrderUtil.storeClose(resultVo);
			} else if (!store.getIsShow()) {
				// 门店不可显示
				logger.error("[checkStore]门店(" + store.getStoreId() + ")不可显示");
				OrderUtil.storeSuspension(resultVo);
			} else if (!store.getIsSale()) {
				// 门店不可交易
				logger.error("[checkStore]门店(" + store.getStoreId() + ")不可交易");
				OrderUtil.storeSuspension(resultVo);
			} else {
				// 验证经销商信息
				result = checkDealer(store.getDealerId(), resultVo);
			}
		} catch (Exception e) {
			logger.error("[checkStore]大屏cpu(" + cpu + ")关联门店查询异常,", e);
			OrderUtil.storeClose(resultVo);
		}
		return result;
	}

	/**
	 * 检验经销商信息
	 * 
	 * @param dealerId
	 * @param resultVo
	 * @return
	 */
	private boolean checkDealer(Integer dealerId, DeliveryResultVo resultVo) {
		boolean result = false;
		try {
			// 根据经销商id查询经销商信息
			DealerDto dealer = dealerService.getDealerById(dealerId);
			if (dealer == null) {
				logger.error("[checkDealer]经销商(" + dealerId + ")未查到");
				OrderUtil.storeClose(resultVo);
			} else if (DealerStatusEnum.SUSPENSION.getValue() == dealer.getStatus()) {
				logger.error("[checkDealer]经销商(" + dealerId + ")暂停营业");
				OrderUtil.storeSuspension(resultVo);
			} else if (DealerStatusEnum.CLOSE.getValue() == dealer.getStatus()) {
				logger.error("[checkDealer]经销商(" + dealerId + ")终止合作");
				OrderUtil.storeClose(resultVo);
			} else {
				resultVo.setResult(true);
				result = true;
			}
		} catch (Exception e) {
			logger.error("[checkDealer]经销商(" + dealerId + ")查询异常:", e);
			OrderUtil.storeClose(resultVo);
		}
		return result;
	}

	/**
	 * 验证订单信息
	 *
	 * @param order
	 * @param resultVo
	 * @return
	 */
	private boolean checkOrder(OrderBizDto order, DeliveryResultVo resultVo) {
		boolean result = true;
		if (order == null) {
			resultVo.setResult(false);
			resultVo.setExplain("订单不存在！");
			result = false;
		} else if (OrderTypeEnum.EXCLUSIVEL.equals(order.getType())) {
			// 专属订单
			OrderExclusivelBizDto orderExclusivel = (OrderExclusivelBizDto) order;
			if (!OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderExclusivel.getOrderStatus())) {
				resultVo.setResult(false);
				resultVo.setExplain("订单状态已改变！");
				result = false;
			}
		} else if (OrderTypeEnum.SUBSCRIBE.equals(order.getType())) {
			// 订阅订单
			OrderSubscribeBizDto orderSubscribe = (OrderSubscribeBizDto) order;
			if (!OrderSubscribeStatusEnum.TRADE_UNDELIVERY.equals(orderSubscribe.getOrderStatus())) {
				resultVo.setResult(false);
				resultVo.setExplain("订单状态已改变！");
				result = false;
			}
		}
		return result;
	}
	
	/**
	 * 发送防诈骗短信
	 * @param phone
	 */
	private void sendSmsPreventFraud(String phone) {
		try {
			smsBizService.sendMessage(phone, SmsTemplateEnum.PREVENT_FRAUD.getValue(),
					null, null);
		} catch (Exception e) {
			logger.error("发送短信异常",e);
		}
	}
}
